home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / formats / urt / rle.doc < prev    next >
Text File  |  1994-10-02  |  31KB  |  866 lines

  1.  
  2.                          DESIGN OF THE UTAH RLE FORMAT
  3.  
  4.                                Spencer W. Thomas
  5.  
  6.               University of Utah, Department of Computer Science
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.                                    ABSTRACT
  16.  
  17.       The  Utah  RLE  (Run Length Encoded) format is designed to provide an
  18.     efficient, device  independent  means  of  storing  multi-level  raster
  19.     images.    Images of arbitrary size and depth can be saved.  The design
  20.     of the format is presented, followed by  descriptions  of  the  library
  21.     routines used to create and read RLE format files.
  22.  
  23. 1. Introduction
  24.   The Utah RLE (Run Length Encoded) format is designed to provide an efficient,
  25. device independent means of storing multi-level  raster  images.    It  is  not
  26. designed  for  binary  (bitmap) images.  It is built on several basic concepts.
  27. The central concept is that of a channel.  A channel corresponds  to  a  single
  28. color,  thus  there  are  normally  a  red channel, a green channel, and a blue
  29. channel.  Up to 255 color channels  are  available  for  use;  one  channel  is
  30. reserved  for  "alpha"  data.    Although  the format supports arbitrarily deep
  31. channels, the current implementation is restricted to 8 bits per channel.
  32.  
  33.   Image data is stored in an RLE file in a scanline form,  with  the  data  for
  34. each  channel of the scanline grouped together.  Runs of identical pixel values
  35. are compressed into a count and a  value.    However,  sequences  of  differing
  36. pixels are also stored efficiently (not as a sequence of single pixel runs).
  37.  
  38.   The  file  header  contains  a  large  amount of information about the image,
  39. including its size, the number of channels  saved,  whether  it  has  an  alpha
  40. channel,  an optional color map, and comments.  The comments may be used to add
  41. arbitrary extra information to the saved image.
  42.  
  43.   A subroutine interface has been written to allow programs to read  and  write
  44. files  in  the  RLE  format.  Two interfaces are available, one that completely
  45. interprets the RLE file and returns scanline pixel data, and one that returns a
  46. list  of  "raw"  run  and  pixel  data.  The second is more efficient, but more
  47. difficult to use, the first is easy to use, but slower.
  48.  
  49.   The Utah RLE format has been used to save images from many  sources,  and  to
  50. display  saved  images  on  many  different  displays  and  from many different
  51. computers.
  52.  
  53. 2. Description of RLE Format
  54.   All data in the RLE file is treated as  a  byte  stream.    Where  quantities
  55. larger than 8 bits occur, they are written in PDP-11 byte order (low order byte
  56. first).
  57.  
  58.   The RLE file consists of two parts, a header followed by scanline data.   The
  59. header contains general information about the image, while the scanline data is
  60. a stream of operations describing the image itself.
  61.  
  62.  
  63.  
  64. 2.1. The Header
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.                          Figure 2-1:   RLE file header
  90.  
  91.   The header has a fixed part and a variable part.  A diagram of the header  is
  92. shown  in  Figure  2-1.    The magic number identifies the file as an RLE file.
  93. Following this are the coordinates of the lower left corner of  the  image  and
  94. the size of the image in the X and Y directions.  Images are defined in a first
  95. quadrant coordinate system (origin at the  lower  left,  X  increasing  to  the
  96. right, Y increasing up.)  Thus, the image is enclosed in the rectangle
  97.  
  98.     [xpos,xpos+xsize-1]X[ypos,ypos+ysize-1].
  99.  
  100. The  position  and  size are 16 bit integer quantities; images up to 32K square
  101. may be saved (the sizes should not be negative).
  102.  
  103.   A flags byte follows.  There are currently four flags defined:
  104.  
  105.   ClearFirst   If this flag is set, the image rectangle should first be cleared
  106.                to the background color (q.v.) before reading the scanline data.
  107.  
  108.   NoBackground If  this  flag  is set, no background color is supplied, and the
  109.                ClearFirst flag should be ignored.
  110.  
  111.   Alpha        This flag indicates the presence of an  "alpha"  channel.    The
  112.                alpha channel is used by image compositing software to correctly
  113.                blend anti-aliased edges.  It is stored as channel -1 (255).
  114.  
  115.   Comments     If this flag is set, comments are present in the  variable  part
  116.                of the header, immediately following the color map.
  117.  
  118.   The next byte is treated as an unsigned 8 bit value, and indicates the number
  119. of color channels that were saved.  It  may  have  any  value  from  0  to  254
  120. (channel 255 is reserved for alpha values).
  121.  
  122.   The  pixelbits  byte  gives the number of bits in each pixel.  The only value
  123. currently supported by the software is 8  (in  fact,  this  byte  is  currently
  124. ignored when reading RLE files).  Pixel sizes taking more than one byte will be
  125. packed low order byte first.
  126.  
  127.   The next two bytes describe the size and shape of the color map.    Ncmap  is
  128. the  number  of  color  channels in the color map.  It need not be identical to
  129. ncolors, but interpretation of values of ncmap different from 0, 1, or  ncolors
  130. may  be  ambiguous,  unless  ncolors  is  1.  If ncmap is zero, no color map is
  131. saved.  Cmaplen is the log base 2 of the length of each channel  of  the  color
  132. map.  Thus, a value for cmaplen of 8 indicates a color map with 256 entries per
  133. channel.
  134.  
  135.   Immediately following the fixed header is  the  variable  part  of  the  file
  136. header.  It starts with the background color.  The background color has ncolors
  137. entries; if necessary, it is filled out to an odd number of bytes with a filler
  138. byte  on  the  end  (since  the  fixed header is an odd number bytes long, this
  139. returns to a 16 bit boundary).
  140.  
  141.   Following the background color is the color  map,  if  present.    Color  map
  142. values  are  stored as 16 bit quantities, left justified in the word.  Software
  143. interpreting the color map must apply a shift appropriate to the application or
  144. to  the  hardware  being  used.    This convention permits use of the color map
  145. without knowing the original output precision.  The channels  of  the  map  are
  146. stored  in  increasing  numerical  order  (starting  with  channel 0), with the
  147. entries of each channel stored also in increasing order  (starting  with  entry
  148. 0).  The color map entries for each channel are stored contiguously.
  149.  
  150.   Comments,  if  present,  follow  the color map.  A 16 bit quantity giving the
  151. length of the comment block comes first.  If the length is odd, a  filler  byte
  152. will  be  present  at the end, restoring the 16 bit alignment (but this byte is
  153. not part  of  the  comments).    The  comment  block  contains  any  number  of
  154. null-terminated text strings.  These strings will conventionally be of the form
  155. "name=value", allowing for easy retrieval of specific  information.    However,
  156. there  is  no restriction that a given name appear only once, and a comment may
  157. contain an arbitrary string.  The intent of  the  comment  block  is  to  allow
  158. information to be attached to the file that is not specifically provided for in
  159. the RLE format.
  160.  
  161.  
  162.  
  163. 2.2. The Scanline Data
  164.   The scanline data  consists  of  a  sequence  of  operations,  such  as  Run,
  165. SetChannel,  and  Pixels,  describing  the  actual  image.   An image is stored
  166. starting at the lower left corner and proceeding upwards in order of increasing
  167. scanline  number.    Each  operation  and  its associated data takes up an even
  168. number of bytes, so that all operations begin on a 16 bit boundary.  This makes
  169. the implementation more efficient on many architectures.
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.                     Figure 2-2:   RLE file operand formats
  186.  
  187.   Each  operation  is  identified  by an 8 bit opcode, and may have one or more
  188. operands.  Single operand operations fit into a  single  16  bit  word  if  the
  189. operand  value is less than 256.  So that operand values are not limited to the
  190. range 0..255, each operation has a long variant, in which  the  byte  following
  191. the  opcode  is  ignored  and the following word is taken as a 16 bit quantity.
  192. The long variant of an opcode is indicated by  setting  the  bit  0x40  in  the
  193. opcode (this allows for 64 opcodes, of which 6 have been used so far.)  The two
  194. single operand formats are shown pictorially in Figure 2-2.
  195.  
  196.   The individual operations will now be discussed in detail.  The  descriptions
  197. are  phrased  in  terms  of the actions necessary to interpret the file.  Three
  198. indices are necessary: the current channel, the scanline number, and the  pixel
  199. index.  The current channel is the channel to which data operations apply.  The
  200. scanline number is just the Y position of the scanline in the image.  The pixel
  201. index is the X position of the pixel within the scanline.  The operations are:
  202.  
  203.   SkipLines    Increment  the  scanline  number  by  the  operand  value.  This
  204.                operation terminates the current  scanline.    The  pixel  index
  205.                should be reset to the xpos value from the header.
  206.  
  207.   SetColor     Set  the  current  channel to the operand value.  This operation
  208.                does not have a long variant.  Note that an operand value of 255
  209.                will  be interpreted as a -1, indicating the alpha channel.  All
  210.                other operand values are positive.  The pixel index is reset  to
  211.                the xpos value.
  212.  
  213.   SkipPixels   Skip over pixels in the current scanline.  Increment pixel index
  214.                by the operand value.   Pixels  skipped  will  be  left  in  the
  215.                background color.
  216.  
  217.   PixelData    Following this opcode is a sequence of pixel values.  The length
  218.                of the sequence is given by the operand value.  If the length of
  219.                the  sequence  is  odd, a filler byte is appended.  Pixel values
  220.                are inserted into the scanline in increasing X order.  The pixel
  221.                index is incremented by the sequence length.
  222.  
  223.   Run          This  is  the only two operand opcode.  The first operand is the
  224.                length (N) of the run.  The second operand is the  pixel  value,
  225.                followed  by  a  filler  byte  if necessary(E.g., a 16 bit pixel
  226.                value would not need a filler byte.).  The next N pixels in  the
  227.                scanline  are  set to the given pixel value.  The pixel index is
  228.                incremented by N, to point to the pixel following the run.
  229.  
  230.   EOF          This opcode has no operand, and indicates the  end  of  the  RLE
  231.                file.    It  is  provided  so that RLE files may be concatenated
  232.                together  and  still  be  correctly  interpreted.    It  is  not
  233.                required,  a  physical end of file will also indicate the end of
  234.                the RLE data.
  235.  
  236.  
  237.  
  238. 2.3. Subroutine Interface
  239.   Two similar subroutine interfaces are provided for reading and writing  files
  240. in  the  RLE format.  Both read or write a scanline worth of data at a time.  A
  241. simple "row" interface communicates in terms of arrays of pixel values.  It  is
  242. simple  to  use,  but  slower  than  the  "raw" interface, which uses a list of
  243. "opcode" values as its communication medium.
  244.  
  245.   In both cases, the interface must be initialized by calling a setup function.
  246. The two types of calls may be interleaved; for example, in a rendering program,
  247. the background could be written using  the  "raw"  interface,  while  scanlines
  248. containing image data could be converted with the "row" interface.  The package
  249. allows multiple RLE streams to be open simultaneously, as is necessary for  use
  250. in  a  compositing  tool,  for  example.  All data relevant to a particular RLE
  251. stream is contained in a "globals" structure.
  252.  
  253.   The globals structure echoes the format of the RLE header.   The  fields  are
  254. described below:
  255.  
  256.   dispatch     The  RLE  creation routines are capable of writing various types
  257.                of output files in addition to RLE.  This value is an index into
  258.                a dispatch table.  This value is initialized by sv_setup.
  259.  
  260.   ncolors      The  number  of  color  channels in the output file.  Up to this
  261.                many color channels will be saved, depending on  the  values  in
  262.                the channel bitmap (see below).
  263.  
  264.   bg_color     A  pointer  to  an  array  of  ncolors  integers  containing the
  265.                background color.
  266.  
  267.   alpha        If this is non-zero, an  alpha  channel  will  be  saved.    The
  268.                presence  or  absence  of  an alpha channel has no effect on the
  269.                value in ncolors.
  270.  
  271.   background   Indicates how to treat background pixels.  It has the  following
  272.                values:
  273.  
  274.                0    Save all pixels, the background color is ignored.
  275.  
  276.                1    Save  only  non-background pixels, but don't set the "clear
  277.                     screen" bit.  This indicates "overlay" mode, a  cheap  form
  278.                     of compositing (but see note below about this.)
  279.  
  280.                2    Save  only  non-background  pixels, clear the screen to the
  281.                     background color before restoring the image.
  282.  
  283.   xmin, xmax, ymin, ymax
  284.                Inclusive bounds of the image region being saved.
  285.  
  286.   ncmap        Number of channels of color map to be saved.  The color map will
  287.                not be saved if this is 0.
  288.  
  289.   cmaplen      Log base 2 of the number of entries in each channel of the color
  290.                map.
  291.  
  292.   cmap         Pointer  to an array containing the color map.  The map is saved
  293.                in "channel major" order.  Each entry in the map  is  a  16  bit
  294.                value  with the color value left justified in the word.  If this
  295.                pointer is NULL, no color map will be saved.
  296.  
  297.   comments     Pointer to an array of  pointers  to  strings.    The  array  is
  298.                terminated  by  a  NULL  pointer  (like  argv or envp).  If this
  299.                pointer is NULL or if the first pointer it points  to  is  NULL,
  300.                comments will not be saved.
  301.  
  302.   fd           File  (FILE *) pointer to be used for writing or reading the RLE
  303.                file.
  304.  
  305.   bits         A bitmap containing 256 bits.   A  channel  will  be  saved  (or
  306.                retrieved)  only  if the corresponding bit is set in the bitmap.
  307.                The alpha channel corresponds to bit 255.  The bitmap allows  an
  308.                application   to  easily  ignore  color  channel  data  that  is
  309.                irrelevant to it.
  310.  
  311.   The globals structure also contains private data for use by the  RLE  reading
  312. and  writing  routines;  data  that  must be maintained between calls, but that
  313. applies to each stream separately.
  314.  
  315.  
  316.  
  317. 2.4. Writing RLE files
  318.   To create  a  run-length  encoded  file,  one  first  initializes  a  globals
  319. structure  with  the relevant information about the image, including the output
  320. file descriptor.  The output file should be open and empty.    Then  one  calls
  321. sv_setup:
  322.  
  323.     sv_setup( RUN_DISPATCH, &globals );
  324.  
  325. This  writes the file header and initializes the private portions of the global
  326. data structure for use by the RLE file writing routines.
  327.  
  328.   The image data must be available or expressible in a scanline order (with the
  329. origin  at  the  bottom of the screen).  After each scanline is computed, it is
  330. written to the output file by calling one of sv_putrow  or  sv_putraw.    If  a
  331. vertical  interval  of  the  image  has  no  data, it may be skipped by calling
  332. sv_skiprow:
  333.  
  334.     /* Skip nrow scanlines */
  335.     sv_skiprow( &globals, nrow );
  336.  
  337.   If the image data for a scanline is available as an array  of  pixel  values,
  338. sv_putrow  should be used to write the data to the output file.  As an example,
  339. let us assume that we have a 512 pixel long scanline, with three color channels
  340. and no alpha data.  We could call sv_putrow as follows:
  341.  
  342.     rle_pixel scandata[3][512], *rows[3];
  343.     int i;
  344.  
  345.     for ( i = 0; i < 3; i++ )
  346.         rows[i] = scandata[i];
  347.     sv_putrow( rows, 512, &globals );
  348.  
  349. Note  that sv_putrow is passed an array of pointers to vectors of pixels.  This
  350. makes it easy to pass  arbitrarily  many,  and  to  specify  values  of  rowlen
  351. different from the size of (e.g.) the scandata array.
  352.  
  353.   The  first element of each row of pixels is the pixel at the xmin location in
  354. the scanline.  Therefore, when saving only  part  of  an  image,  one  must  be
  355. careful to set the rows pointers to point to the correct pixel in the scanline.
  356.  
  357.   If  an  alpha  channel  is  specified  to  be saved, things get a little more
  358. complex.  Here is the same example, but now with an alpha channel being saved.
  359.  
  360.     rle_pixel scandata[3][512],
  361.               alpha[512], *rows[4];
  362.     int i;
  363.  
  364.     rows[0] = alpha;
  365.     for ( i = 0; i < 3; i++ )
  366.         rows[i+1] = scandata[i];
  367.     sv_putrow( rows+1, 512, &globals );
  368.  
  369. The sv_putrow routine expects to find the pointer to the alpha channel  at  the
  370. -1  position in the rows array.  Thus, we pass a pointer to rows[1] and put the
  371. pointer to the alpha channel in rows[0].
  372.  
  373.   Finally, after all scanlines have been written, we call sv_puteof to write an
  374. EOF opcode into the file.  This is not strictly necessary, since a physical end
  375. of file also indicates the end of the RLE data, but it is a good idea.
  376.  
  377.   Here is a skeleton of an application that uses sv_putrow to save an image  is
  378. shown  in  Figure  2-3.    This example uses the default values supplied in the
  379. globals variable sv_globals, modifying it to indicate the presence of an  alpha
  380. channel.
  381.  
  382.   Using  sv_putraw is more complicated, as it takes arrays of rle_op structures
  383. instead of just pixels.  If the data is already available in something close to
  384. this  form,  however,  sv_putraw will run much more quickly than sv_putrow.  An
  385. rle_op is a structure with the following contents:
  386.  
  387.   opcode       The type of data.  One of ByteData or RunData.
  388.  
  389.   xloc         The X location within the scanline at which this data begins.
  390.  
  391.   length       The length of the data.  This is either  the  number  of  pixels
  392.                that  are  the  same  color,  for a run, or the number of pixels
  393.                provided as byte data.
  394.  
  395.   pixels       A pointer to an array of pixel values.  This field is used  only
  396.                for the ByteData opcode.
  397.  
  398.   run_val      The pixel value for a RunData opcode.
  399.  
  400.   Since  there  is  no guarantee that the different color channels will require
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.     #include <svfb_global.h>
  502.  
  503.     main()
  504.     {
  505.             rle_pixel scanline[3][512], alpha[512], *rows[4];
  506.             int y, i;
  507.  
  508.             /* Most of the default values in sv_globals are ok */
  509.             /* We do have an alpha channel, though */
  510.             sv_globals.sv_alpha = 1;
  511.             SV_SET_BIT( sv_globals, SV_ALPHA );
  512.  
  513.             rows[0] = alpha;
  514.             for ( i = 0; i < 3; i++ )
  515.                     rows[i+1] = scanline[i];
  516.  
  517.             sv_setup( RUN_DISPATCH, &sv_globals );
  518.  
  519.             /* Create output for 512 x 480 (default size) display */
  520.             for ( y = 0; y < 480; y++ )
  521.             {
  522.                     mk_scanline( y, scanline, alpha );
  523.                     sv_putrow( rows, 512, &sv_globals );
  524.             }
  525.             sv_puteof( &sv_globals );
  526.     }
  527.  
  528.                    Figure 2-3:   Example of use of sv_putrow
  529.  
  530. the same set of rle_ops to describe  their  data,  a  separate  count  must  be
  531. provided for each channel.  Here is a sample call to sv_putraw:
  532.  
  533.     int nraw[3];    /* Length of each row */
  534.     rle_op *rows[3];/* Data pointers */
  535.     sv_putraw( rows, nraw, &globals );
  536.  
  537. A  more  complete  example  of the use of sv_putraw will be given in connection
  538. with the description of rle_getraw, below.
  539.  
  540.   Calls to sv_putrow and sv_putraw may be freely intermixed, as required by the
  541. application.
  542.  
  543.  
  544.  
  545. 2.5. Reading RLE Files
  546.   Reading  an  RLE  file  is much like writing one.  An initial call to a setup
  547. routine reads the file header and fills in the  globals  structure.    Then,  a
  548. scanline at a time is read by calling rle_getrow or rle_getraw.
  549.  
  550.   The  calling  program  is  responsible for opening the input file.  A call to
  551. rle_get_setup will then read the header information and fill  in  the  supplied
  552. globals  structure.   The return code from rle_get_setup indicates a variety of
  553. errors, such as the input file not being an RLE file, or  encountering  an  EOF
  554. while reading the header.
  555.  
  556.   Each time rle_getrow is called, it fills in the supplied scanline buffer with
  557. one scanline of image data and returns the Y position of  the  scanline  (which
  558. will  be  one  greater than the previous time it was called).  Depending on the
  559. setting of the background flag, the scanline buffer may or may not  be  cleared
  560. to the background color on each call.  If it is not (background is 0 or 1), and
  561. if the caller does not clear the buffer between scanlines,  then  a  "smearing"
  562. effect will be seen, if some pixels from previous scanlines are not overwritten
  563. by pixels on the current scanline.  Note that  if  background  is  0,  then  no
  564. background  color  was  supplied,  and  setting  background  to 2 to try to get
  565. automatic  buffer  clearing  will  usually  cause  a  segmentation  fault  when
  566. rle_getrow tries to get the background color through the bg_color pointer.
  567.  
  568.   Figure  2-4  shows  an  example  of  the use of rle_getrow.  Note the dynamic
  569. allocation of scanline storage space, and compensation for presence of an alpha
  570. channel.    A subroutine, rle_row_alloc, is available that performs the storage
  571. allocation automatically.  It is described below.  If the  alpha  channel  were
  572. irrelevant,  the  macro  SV_CLR_BIT could be used to inhibit reading it, and no
  573. storage space would be needed for it.
  574.  
  575.   The function rle_getraw is the inverse of sv_putraw.  When called,  it  fills
  576. in  the  supplied  buffer  with raw data for a single scanline.  It returns the
  577.                          15
  578. scanline y position, or 2   to indicate end of file.  It  is  assumed  that  no
  579.                                 15
  580. image  will  have  more  than  2  -1 scanlines.  A complete program (except for
  581. error checking) that reads an RLE file  from  standard  input  and  produces  a
  582. negative image on standard output is shown in Figure 2-5.
  583.  
  584.   The  functions  rle_row_alloc and rle_raw_alloc simplify allocation of buffer
  585. space for use by the rle routines.  Both use a supplied  globals  structure  to
  586. determine how many and which channels need buffer space, as well as the size of
  587. the buffer for each scanline.  The returned buffer pointers  will  be  adjusted
  588. for the presence of an alpha channel, if it is present.  Buffer space for pixel
  589. or rle_op data will be allocate only for those channels that have bits  set  in
  590. the  channel  bitmap.  The buffer space may be freed by calling rle_row_free or
  591. rle_raw_free, respectively.
  592.  
  593. 3. Comments, issues, and directions
  594.   Some comments on the file format and current subroutine implementation:
  595.  
  596.    - The background color for the alpha channel is always 0.
  597.  
  598.    - All channels must have the same number of bits.    This  could  be  a
  599.      problem  when  saving,  e.g.,  Z  values,  or  if more than 8 bits of
  600.      precision were desired for the alpha channel.
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.     /* An example of using rle_getrow */
  702.     /* Scanline pointer */
  703.     rle_pixel ** scan;
  704.     int i;
  705.  
  706.     /* Read the RLE file from stdin */
  707.     rle_get_setup( &globals );
  708.  
  709.     /* Allocate enough space for scanline data, including alpha channel */
  710.     /* (Should check for non-zero return, indicating a malloc error) */
  711.     rle_row_alloc( &globals, &scan );
  712.  
  713.     /* Read scanline data */
  714.     while ( (y = rle_getrow( &globals, stdin, scan ) <= globals.sv_ymax )
  715.             /* Use the scanline data */;
  716.  
  717.  
  718.                    Figure 2-4:   Example of rle_getrow use.
  719.  
  720.  
  721.     #include <stdio.h>
  722.     #include <svfb_global.h>
  723.     #include <rle_getraw.h>
  724.  
  725.     main()
  726.     {
  727.         struct sv_globals in_glob, out_glob;
  728.         rle_op ** scan;
  729.         int * nraw, i, j, c, y, newy;
  730.  
  731.         in_glob.svfb_fd = stdin;
  732.         rle_get_setup( &in_glob );
  733.         /* Copy setup information from input to output file */
  734.         out_glob = in_glob;
  735.         out_glob.svfb_fd = stdout;
  736.  
  737.         /* Get storage for calling rle_getraw */
  738.         rle_raw_alloc( &in_glob, &scan, &nraw );
  739.  
  740.         /* Negate background color! */
  741.         if ( in_glob.sv_background )
  742.             for ( i = 0; i < in_glob.sv_ncolors; i++ )
  743.                 out_glob.sv_bg_color[i] = 255 - out_glob.sv_bg_color[i];
  744.  
  745.         /* Init output file */
  746.         sv_setup( RUN_DISPATCH, &out_glob );
  747.  
  748.         y = in_glob.sv_ymin;
  749.         while ( (newy = rle_getraw( &in_glob, scan, nraw )) != 32768 ) {
  750.             /* If > one line skipped in input, do same in output */
  751.             if ( newy - y > 1 )
  752.                 sv_skiprow( &out_glob, newy - y );
  753.             y = newy;
  754.             /* Map all color channels */
  755.             for ( c = 0; c < out_glob.sv_ncolors; c++ )
  756.                 for ( i = 0; i < nraw[c]; i++ )
  757.                     switch( scan[c][i].opcode ) {
  758.                     case RRunDataOp:
  759.                         scan[c][i].u.run_val = 255 - scan[c][i].u.run_val;
  760.                         break;
  761.                     case RByteDataOp:
  762.                         for ( j = 0; j < scan[c][i].length; j++ )
  763.                             scan[c][i].u.pixels[j] =
  764.                                 255 - scan[c][i].u.pixels[j];
  765.                         break;
  766.                     }
  767.             sv_putraw( scan, nraw, &out_glob );
  768.             /* Free raw data */
  769.             rle_freeraw( &in_glob, scan, nraw );
  770.         }
  771.         sv_puteof( &out_glob );
  772.  
  773.         /* Free storage */
  774.         rle_raw_free( &in_glob, scan, nraw );
  775.     }
  776.  
  777.  
  778.             Figure 2-5:   Program to produce a negative of an image
  779.  
  780.    - Pixels are skipped (by sv_putrow) only if all channel values  of  the
  781.      pixel are equal to the corresponding background color values.
  782.  
  783.    - The current Implementation of sv_putrow skips pixels only if at least
  784.      2 adjacent pixels are  equal  to  the  background.    The  SkipPixels
  785.      operation   is   intended   for  efficiency,  not  to  provide  cheap
  786.      compositing.
  787.  
  788.    - Nothing forces the image data to lie within the  bounds  declared  in
  789.      the header.  However, rle_getrow will not write outside these bounds,
  790.      to prevent core dumps.  No such protection is provided by rle_getraw.
  791.  
  792.    - Images saved in RLE are usually about 1/3 their original size (for an
  793.      "average"  image).   Highly complex images may end up slightly larger
  794.      than they would have been if saved by the trivial method.
  795.  
  796.   We have not yet decided how pixels with other than 8 bits  should  be  packed
  797. into  the file.  To keep the file size down, one would like to pack ByteData as
  798. tightly as possible.  However, for interpretation speed, it would  probably  be
  799. better to save one value in each (pixelbits+7)/8 bytes.
  800.  
  801.   Some proposed enhancements include:
  802.  
  803.    - A "ramp" opcode.  This specifies that pixel values should be linearly
  804.      ramped between two values  for  a  given  number  of  pixels  in  the
  805.      scanline.   This opcode would be difficult to generate from an image,
  806.      but if an application knew it was generating a ramp, it could produce
  807.      significant file size savings (e.g.  in Gouraud shaded images).
  808.  
  809.    - Opcodes  indicating  that  the  current  scanline is identical to the
  810.      previous, or that it differs only slightly  (presumably  followed  by
  811.      standard  opcodes indicating the difference).  Detection of identical
  812.      scanlines is easy, deciding that a scanline differs  slightly  enough
  813.      to  warrant a differential description could be difficult.  In images
  814.      with  large  areas  with  little  change,  this  could  produce  size
  815.      savings(This  suggestion  was  inspired  by  a description of the RLE
  816.      format used at Ohio State University.)
  817.  
  818.   The subroutine library is still missing some useful functions.  Some proposed
  819. additions are:
  820.  
  821.    - Conversion from "raw" to "row" format, and back.  One could then view
  822.      sv_putrow as being a "raw" to "row" conversion followed by a call  to
  823.      sv_putraw,  and  rle_getrow as a call to rle_getraw followed by "row"
  824.      to "raw" conversion.
  825.  
  826.    - A function to merge several channels of  "raw"  data  into  a  single
  827.      channel.   For example, this would take separate red, green, and blue
  828.      channels and combine them into a single RGB channel.  This  would  be
  829.      useful  for  RLE interpretation on devices that do not easily support
  830.      the separate channel paradigm, while preserving the efficiency of the
  831.      "raw" interface.  It could also be used to increase the efficiency of
  832.      a compositing program.
  833.  
  834.   The Utah RLE format has developed and matured over  a  period  of  about  six
  835. years,  and  has  proven  to  be  versatile  and  useful  for a wide variety of
  836. applications that require  image  transmittal  and  storage.    It  provides  a
  837. compact,  efficiently  interpreted  image storage capability.  We expect to see
  838. continued development of capabilities  and  utility,  but  expect  very  little
  839. change in the basic format.
  840.  
  841. 4. Acknowledgments
  842.   This   work  was  supported  in  part  by  the  National  Science  Foundation
  843. (DCR-8203692 and DCR-8121750), the Defense Advanced  Research  Projects  Agency
  844. (DAAK11-84-K-0017), the Army Research Office (DAAG29-81-K-0111), and the Office
  845. of Naval Research (N00014-82-K-0351).  All opinions, findings,  conclusions  or
  846. recommendations  expressed in this document are those of the authors and do not
  847. necessarily reflect the views of the sponsoring agencies.
  848.  
  849.                                Table of Contents
  850. 1. Introduction                                                               0
  851. 2. Description of RLE Format                                                  0
  852.      2.1. The Header                                                          0
  853.      2.2. The Scanline Data                                                   0
  854.      2.3. Subroutine Interface                                                1
  855.      2.4. Writing RLE files                                                   1
  856.      2.5. Reading RLE Files                                                   2
  857. 3. Comments, issues, and directions                                           2
  858. 4. Acknowledgments                                                            5
  859.  
  860.                                 List of Figures
  861. Figure 2-1:   RLE file header                                                 0
  862. Figure 2-2:   RLE file operand formats                                        0
  863. Figure 2-3:   Example of use of sv_putrow                                     2
  864. Figure 2-4:   Example of rle_getrow use.                                      3
  865. Figure 2-5:   Program to produce a negative of an image                       4
  866.